﻿icmp_checksum.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct packet_dump
{
	unsigned int size;
	int seq;
	struct packet_dump *next;
	unsigned char  *buf;

	unsigned char version;
	unsigned char IHL;
	unsigned char TOS;
	unsigned char tlength;
	unsigned short ID;
	unsigned  char TTL;
	unsigned  char protocol; 
	unsigned short hchksum;
	unsigned short hchksum_recomputed;
	unsigned char flags;
	unsigned short frag_offset;

	char src[20];
	char dest[20];

	unsigned int options;
	unsigned char padding;

};

unsigned char hexdigit2value(unsigned char c);
int hex2bytes(char *hexstring,unsigned char *bytes);
void init_packetstruct(struct packet_dump *p);
int hpingdump2binary(FILE *in,struct packet_dump **packets);
void print_packet(struct packet_dump *p);
void decode_packet(struct packet_dump *p);
int ones2twos(unsigned short int n);
unsigned short int ones_addition(unsigned short int a, unsigned short int b);


int main()
{
	char buf[1048576],hex_string[1024],input,i;
	unsigned char bytes[1024];
	int buf_size,bytes_size,value;
	struct packet_dump *p;

	hpingdump2binary(stdin,&p);
	

	return 0;
}

int hpingdump2binary(FILE *in,struct packet_dump **packets)
{
	char line[1024];
	unsigned char bytes[1024];
	int i=-1,firsttab =0,packet_frag=0,bytes_size,total_size=0,seq=0;
	struct packet_dump **cur_packet = packets;

	while(fgets(line,1024,in) != NULL)
	{
		if(line[0]  == '\t')
		{
			if(packet_frag == 0)
			{
				packet_frag = 1;
				*cur_packet = malloc(sizeof(struct packet_dump));
				init_packetstruct(*cur_packet);
icmp_checksum.c
				bytes_size = hex2bytes(line,bytes);
				(*cur_packet)->size = bytes_size;
				(*cur_packet)->buf = malloc(bytes_size);
				(*cur_packet)->seq = seq++;
				memcpy((*cur_packet)->buf,bytes,bytes_size);
			}
			else
			{
				bytes_size = hex2bytes(line,bytes);
				(*cur_packet)->buf = realloc((*cur_packet)->buf,(*cur_packet)->size);
				memcpy((*cur_packet)->buf+(*cur_packet)->size,bytes,bytes_size);
				(*cur_packet)->size += bytes_size;
			}

			total_size += bytes_size;
		}
		else if(line[0]  != '\t' && packet_frag == 1)
		{
			printf("*packet%d*\n",seq);
			packet_frag = 0;
			print_packet(*cur_packet);
			cur_packet = &((*cur_packet)->next);
		}
	}

	return total_size;
}

int hex2bytes(char *hexstring,unsigned char *bytes)
{
	int size=0,firstbyte=0,i=0,j=0;
	unsigned char cur=0;	

	for(i=0;hexstring[i] != '\0' && hexstring[i] != '\n';i++)
	{
		cur = hexdigit2value(hexstring[i]);

		if(cur != 255)
		{
			if(firstbyte == 0)
			{
				firstbyte = 1;
				bytes[j] = 16*cur;
			}
			else
			{
				firstbyte = 0;
				bytes[j] += cur;
				j++;
				size++;
			}
		}
	}

	if(firstbyte == 1)
		size = -1;

	return size;
}


unsigned char hexdigit2value(unsigned char c)
{
	unsigned result;
	unsigned char cur = toupper(c);

	if(cur >= 65 && cur <= 70)
		result = cur - 55;
	else if(cur >= 48 && cur <= 57)
		result = cur - 48;
	else
icmp_checksum.c
		result = 255;

	return result;
}

void init_packetstruct(struct packet_dump *p)
{
	p->size = 0;
	p->seq = -1;
	p->buf = NULL;
	p->next = NULL;
}

void print_packet(struct packet_dump *p)
{
	int i;

	if(p == NULL)
			return;

	decode_packet(p);

	for(i=0;i<p->size;i++)
	{
		printf("%d ",p->buf[i]);
	}
	printf("\n");

	printf("Version: %d ",p->version);
	printf("IHL: %d ",p->IHL);
	printf("TOS: %d ",p->TOS);
	printf("Total Length: %d ",p->tlength);
	printf("Identification: %d ",p->ID);
	printf("Flags: %d ",p->flags);
	printf("Frag Offset: %d ",p->frag_offset);
	printf("TTL: %d ",p->TTL);
	printf("Protocol: %d ",p->protocol);
	printf("Header Chksum: %d ",(unsigned short int)p->hchksum);
	printf("Source Add: %s ",p->src);
	printf("Destination Add %s ",p->dest);
	printf("Options: %d ",p->options);
	printf("Padding: %d\n",p->padding);
}

void decode_packet(struct packet_dump *p)
{
	int i,j;
	unsigned int checksum = 0,curword=0;

	p->version = ((unsigned char)*(p->buf) >> 4);
	p->IHL = (unsigned char)*(p->buf) & 0x0F;
	p->TOS = (unsigned char)*(p->buf+1);
	p->tlength = ((unsigned short)*(p->buf+2) << 8) | (unsigned short)*(p->buf+3);
	p->ID = ((unsigned short)*(p->buf+4) << 8) | (unsigned short)*(p->buf+5);
	p->flags = (unsigned char)*(p->buf+6) >> 4;
	p->frag_offset = (((unsigned short)*(p->buf+6) << 8) & 0x0F) | (unsigned short)*(p->buf+7);
	p->TTL = (unsigned char)*(p->buf+8);;
	p->protocol =(unsigned char)*(p->buf+9);;
	p->hchksum =((unsigned short)*(p->buf+10) << 8) | (unsigned short)*(p->buf+11);;
	
sprintf(p->src,"%u.%u.%u.%u\0",p->buf[12],p->buf[13],p->buf[14],p->buf[15]);
sprintf(p->dest,"%u.%u.%u.%u\0",p->buf[16],p->buf[17],p->buf[18],p->buf[19]);

	j=0;
	for(i=0;i<p->IHL*2;i++)
	{
		if(j==10) {j+=2;continue;}
		curword = ((unsigned short)*(p->buf+j) << 8) | (unsigned short)*(p->buf+j+1);
		checksum = ones_addition(curword,checksum);
		printf("number to add: %u\t",curword);
		printf("new sum: %u\n",checksum);
icmp_checksum.c
		j += 2;
	}
	checksum = checksum ^ 0xFFFF;
	p->hchksum_recomputed = checksum;
	printf("new sum: %d\n",checksum);
}

int ones2twos(unsigned short int n)
{
	int sign,base;

	sign = n &  0x8000;
	base = n &  0x7FFF;

	if(n == 0)
		return n;
	else
		return n * -1;
}

unsigned short int ones_addition(unsigned short int a, unsigned short int b)
{
	unsigned int tmp;

	tmp = (unsigned int)a;
	tmp  += (unsigned int)b;

	tmp = (tmp >> 16) + (tmp & 0xFFFF);

	return (unsigned short int)tmp;
}
